package com.hwadee.property.aspect;

import com.hwadee.property.service.IUserActivityLogService;
import com.hwadee.property.service.IUserService;
import com.hwadee.property.util.JwtUtil;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class ControllerAspect {

    @Autowired
    private IUserActivityLogService logService; // 日志服务类

    @Autowired
    private IUserService userService;

    @Autowired
    private JwtUtil jwtUtil;


    // 定义切点，匹配 Controller 包下的所有方法
    @Pointcut("execution(* com.hwadee.property.controller..*(..)) " +
            "&& !execution(* com.hwadee.property.controller.charge.AliPayController.*(..)) " +
            "&& !execution(* com.hwadee.property.controller.info.UserActivityLogController.*(..)) " +
            "&& !execution(* com.hwadee.property.controller.people.UserController.login(..)) " +
            "&& !execution(* com.hwadee.property.controller.people.AdministratorController.login(..))")
    public void controllerMethods() {}

    // 在方法执行后执行日志记录
    @AfterReturning(pointcut = "controllerMethods()")
    public void logActivity(JoinPoint joinPoint) {
        // 获取目标方法的Method对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        // 获取@ApiOperation注解的value属性值
        ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);

        // 获取Controller类名
        String controllerClassName = joinPoint.getTarget().getClass().getSimpleName();

        // 获取方法的参数名
        String[] parameterNames = signature.getParameterNames();
        // 获取方法的参数值
        Object[] args = joinPoint.getArgs();

        // 初始化日志参数
        Double amount = null; // 涉及金额
        StringBuilder relatedRecordIDBuilder = null; // 使用StringBuilder优化拼接, 关联记录为收费项目的id
        // 遍历参数名和参数值，匹配amount和relatedRecordID
        // 其中 relatedRecordID 优先匹配 chargeId, 其次匹配 ownerId
        for (int i = 0; i < parameterNames.length; i++) {
            String paramName = parameterNames[i];
            Object paramValue = args[i];

            // 匹配金额参数
            if ("amount".equals(paramName)) {
                amount = (Double) paramValue;
            }

            // 匹配后缀为ID或Id的参数
            if ((paramName.endsWith("ID") || paramName.endsWith("Id")) && paramValue != null) {
                if (relatedRecordIDBuilder == null) {
                    relatedRecordIDBuilder = new StringBuilder(paramName + ":" + paramValue);
                } else {
                    relatedRecordIDBuilder.append(", ").append(paramName).append(":").append(paramValue);
                }
            }
        }
        // 将StringBuilder转换为字符串
        String relatedRecordID = relatedRecordIDBuilder != null ? relatedRecordIDBuilder.toString() : null;


        // 获取当前请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            // 从请求头中获取token
            String token = request.getHeader("Authorization");
            if (token != null) {
                // 解析token获取userId
                Long userId = jwtUtil.getUserId(token); // 该userId指向行动的主体
                int userType = jwtUtil.getUserType(token);
                Long communityID = null;
                if (userType != 0){
                    communityID = userService.getById(userId).getCommunityId();
                }
                String content = apiOperation != null ? apiOperation.value() : "No description";
                if (userType == 0) {
                    if (!content.startsWith("【管理员】")) {
                        content = "【管理员】调用：" + content;
                    }
                }
                // 根据类名设置日志类型
                String logType = getLogTypeByControllerName(controllerClassName);

                // 调用日志保存方法
                logService.saveActivityLog(userId, communityID, content, amount, logType, relatedRecordID);
            }
        }
    }

    // 根据Controller类名设置日志类型
    private String getLogTypeByControllerName(String controllerClassName) {
        Map<String, String> logTypeMap = new HashMap<>();
        logTypeMap.put("ChargeDetail", "【缴费详情】ChargeDetail");
        logTypeMap.put("ChargeItem", "【缴费项目】ChargeItem");
        logTypeMap.put("Building", "【楼栋】Building");
        logTypeMap.put("Community", "【小区】Community");
        logTypeMap.put("House", "【房子】House");
        logTypeMap.put("Complain", "【投诉建议】Complain");
        logTypeMap.put("Notice", "【通知】Notice");
        logTypeMap.put("Repair", "【报修】Repair");
        logTypeMap.put("Parking", "【停车位】Parking");
        logTypeMap.put("ParkingUse", "【车位使用】ParkingUse");
        logTypeMap.put("Administrator", "【管理员】Administrator");
        logTypeMap.put("User", "【用户】User");

        for (String key : logTypeMap.keySet()) {
            if (controllerClassName.startsWith(key)) {
                return logTypeMap.get(key);
            }
        }

        return "【其他】"; // 默认值
    }

}
